﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HslCommunication;

namespace Net_SCADA
{
    public class hsl_Client
    {
        public hsl_Server server { get; set; }
        public List<hsl_Item> hslitems { get; set; } = new List<hsl_Item>();
        private List<hsl_Group> hslgroup { get; set; } = new List<hsl_Group>();
        public List<object> ItemValues { get; private set; } = new List<object>();
        public List<object> SetValues { get; set; } = new List<object>();
        public bool IsNeedSetValue { get; set; } = false;
        public hsl_Client() { }
        public hsl_Client(hsl_Server server)
        {
            this.server = server;
        }
        public void InstallHslItems(List<string> v)
        {
            if (v == null) return;
            for (int i = 0; i < v.Count; i++)
            {
                hslitems.Add(new hsl_Item(v[i]));
                if(hsl_Function.OpcaddToHsladd(v[i],out string grpadd,out string datatype,out int byteoffset,out int bitoffset,out int bytelength))
                {
                    hsl_Group grp = hslgroup.Find(x => x.GroupAdd == grpadd);
                    if (grp == null)//如果列表中没有相关的group，添加一个并初始化
                    {
                        grp = new hsl_Group() { 
                            GroupAdd = grpadd, 
                            ByteOffset= byteoffset,
                            ByteLength=bytelength + byteoffset
                        };
                        hslgroup.Add(grp);
                    }else//已经存在相关的group，更新offset和length
                    {
                        //计算读取长度。
                        if (byteoffset < grp.ByteOffset)
                            grp.ByteOffset = byteoffset;
                        if (grp.ByteLength < (bytelength + byteoffset))
                            grp.ByteLength = bytelength + byteoffset;
                    }
                    hslitems[i].group = grp;
                    hslitems[i].ByteOffset = byteoffset;
                    hslitems[i].ByteLength = bytelength;
                    hslitems[i].bitOffset = bitoffset;
                    hslitems[i].DataType = datatype;
                }
            }
        }
        public void GetDataFromPLC()
        {
            if (server!=null && server.isPlCConnected)
            {

                //根据group的设置，从PLC中获取总体的数据为byte数组
                for (int i = 0; i < hslgroup.Count; i++)
                {
                    StringBuilder sb = new StringBuilder();
                    if(hslgroup[i].GroupAdd=="Q" || hslgroup[i].GroupAdd == "I" || hslgroup[i].GroupAdd == "M")
                        sb.Append(hslgroup[i].GroupAdd).Append(hslgroup[i].ByteOffset);
                    else
                        sb.Append(hslgroup[i].GroupAdd).Append(".").Append(hslgroup[i].ByteOffset);
                    OperateResult<byte[]> res = server.SiemensPLC.Read(sb.ToString(), (ushort)(hslgroup[i].ByteLength - hslgroup[i].ByteOffset));
                    if (res.IsSuccess)
                        hslgroup[i].GroupValue = res.Content;
                    else
                        Console.WriteLine("read error for {0} start from {1} with lenght {2}.", hslgroup[i].GroupAdd, hslgroup[i].ByteOffset, hslgroup[i].ByteLength - hslgroup[i].ByteOffset);
                }
                //对每Item进行数据的解析设置
                List<object> lst = new List<object>(); ;
                for (int i = 0; i < hslitems.Count; i++)
                {
                    if (hslitems[i].group.GroupValue != null)
                    {
                        hslitems[i].ItemValue = hsl_Function.GetRealData(hslitems[i].DataType, hslitems[i].group.GroupValue, hslitems[i].ByteOffset - hslitems[i].group.ByteOffset, hslitems[i].bitOffset);
                        lst.Add(hslitems[i].ItemValue);
                    }
                }
                ItemValues = lst;
            }
        }
        public bool SetItemValues(List<object> values)
        {
            if (values.Count != hslitems.Count) return false;//设置的数量需要一致
            bool result = true;
            for (int i = 0; i < hslitems.Count; i++)
            {
                result &= WriteOneValue(i, values[i]);
            }
            IsNeedSetValue = false;
            return result;
        }
        public bool RandemSetItemValues(Dictionary<int,object> values)
        {
            bool result = true;
            foreach (int i in values.Keys)
            {
                if (i >= hslitems.Count) continue;
                result &= WriteOneValue(i, values[i]);
            }
            return result;
        }
        private bool WriteOneValue(int ItemIndex,object value)
        {
            OperateResult res = new OperateResult();
            StringBuilder writeAdd = new StringBuilder().Append(hslitems[ItemIndex].group.GroupAdd).Append(".").Append(hslitems[ItemIndex].ByteOffset);
            if (hslitems[ItemIndex].DataType.ToUpper() == "X")//进行位的写入操作
            {
                //if (bool.TryParse(value.ToString(), out bool v))//仅 “true”和“false”能判断，其他所有数据都判断为false
                //对布尔量重新进行判断
                bool v = !(value.ToString().ToLower() == "0" || value.ToString().ToLower() == "false" || value.ToString().ToLower().Trim() == "");
                {
                    writeAdd.Append(".").Append(hslitems[ItemIndex].bitOffset);
                    res = server.SiemensPLC.Write(writeAdd.ToString(), v);
                }
            }
            else
            {
                byte[] wBytes = hsl_Function.GetSetData(hslitems[ItemIndex].DataType, value);
                if (wBytes != null)//数据解析成功
                {
                    res = server.SiemensPLC.Write(writeAdd.ToString(), wBytes);
                    Console.WriteLine(writeAdd + ":" + value);
                }
                else//数据解析失败
                    return false;
            }
            return res.IsSuccess;
        }
    }
}
